home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / decprom / fs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-31  |  8.4 KB  |  333 lines

  1. /* fs.c -
  2.  *
  3.  *    General filesystem support.
  4.  *
  5.  * Copyright (C) 1985 Regents of the University of California
  6.  * All rights reserved.
  7.  */
  8.  
  9. #ifdef notdef
  10. static char rcsid[] = "$Header: /sprite/src/boot/decprom/RCS/fs.c,v 1.2 90/06/27 14:57:09 shirriff Exp $ SPRITE (Berkeley)";
  11. #endif not lint
  12.  
  13. #include "sprite.h"
  14. #include "fsBoot.h"
  15. #include "kernel/machMon.h"
  16.  
  17. /*
  18.  * For non-block aligned reads.
  19.  */
  20. char    readBuffer[FS_BLOCK_SIZE];
  21.  
  22. /*
  23.  * For lookup
  24.  */
  25. static char    component[FS_MAX_NAME_LENGTH];
  26.  
  27. /*
  28.  * Forward declarations.
  29.  */
  30. void FsGetFileDesc();
  31. void FsInitFileHandle();
  32.  
  33. #define NO_PRINTF
  34.  
  35. /*
  36.  * ----------------------------------------------------------------------------
  37.  *
  38.  * Fs_Open --
  39.  *
  40.  *    Open a file.  This does a simple lookup (based on the kernel's
  41.  *    FsLocalLookup) and creates a handle for the file.
  42.  *
  43.  * Results:
  44.  *    SUCCESS or a return code from various sub-operations.
  45.  *
  46.  * Side effects:
  47.  *    Calls malloc
  48.  *
  49.  * ----------------------------------------------------------------------------
  50.  */
  51.  
  52. ReturnStatus
  53. Fs_Open(fileName, useFlags, permissions, handlePtrPtr)
  54.     char *fileName;
  55.     int useFlags;
  56.     int permissions;
  57.     Fsio_FileIOHandle     **handlePtrPtr;
  58. {
  59.     register ReturnStatus status;
  60.     Fsio_FileIOHandle *curHandlePtr;
  61.     register char *curCharPtr;
  62.     register char *componentPtr;
  63.     register int index;
  64.  
  65.     curCharPtr = fileName;
  66.     while(*curCharPtr == '/') {
  67.     curCharPtr++;
  68.     }
  69.     curHandlePtr = fsRootHandlePtr;
  70.  
  71.     while (*curCharPtr != '\0') {
  72.     if (curHandlePtr->descPtr->fileType != FS_DIRECTORY) {
  73.         return(FS_NOT_DIRECTORY);
  74.     }
  75.         /*
  76.          * Get the next component.
  77.          */
  78.         index = 0;
  79.     componentPtr = component;
  80.         while (*curCharPtr != '/' && *curCharPtr != '\0') {
  81.             *componentPtr++ = *curCharPtr++;
  82.         }
  83.         *componentPtr = '\0';
  84. #ifndef NO_PRINTF
  85.     Mach_MonPrintf(" %s ", component);
  86. #endif
  87.         /*
  88.          * Skip intermediate and trailing slashes so that *curCharPtr
  89.          * is Null when 'component' has the last component of the name.
  90.          */
  91.         while (*curCharPtr == '/') {
  92.             curCharPtr++;
  93.         }
  94.  
  95.     status = FsFindComponent(fsDomainPtr, curHandlePtr, component,
  96.                           &curHandlePtr);
  97.  
  98.     if (status != SUCCESS) {
  99. #ifndef NO_PRINTF
  100.         Mach_MonPrintf("<%x>\n", status);
  101. #endif
  102.         return(status);
  103.     }
  104.     }
  105.     *handlePtrPtr = curHandlePtr;
  106. }
  107.  
  108. /*
  109.  * ----------------------------------------------------------------------------
  110.  *
  111.  * Fs_Read --
  112.  *
  113.  *    Read from a file given its handle.
  114.  *
  115.  * Results:
  116.  *    A return status from the read.
  117.  *
  118.  * Side effects:
  119.  *    buffer is loaded with the data read in.
  120.  *    *readCountPtr is updated to reflect the number of bytes read.
  121.  *
  122.  * ----------------------------------------------------------------------------
  123.  */
  124. ReturnStatus
  125. Fs_Read(handlePtr, offset, numBytes, buffer, readCountPtr)
  126.     register Fsio_FileIOHandle     *handlePtr;
  127.     int            offset;
  128.     int            numBytes;
  129.     register Address    buffer;
  130.     int            *readCountPtr;
  131. {
  132.     int                firstBlock;
  133.     int                lastBlock;
  134.     int                lastByte;
  135.     BlockIndexInfo        indexInfo;
  136.     register    int        readSize;
  137.     register    int        blockAddr;
  138.     register    int        blockOffset;
  139.     register    int        bufferIndex;
  140.     register     ReturnStatus    status;
  141.     register    int        size;
  142.  
  143.     firstBlock = offset / FS_BLOCK_SIZE; 
  144.     lastByte = offset + numBytes - 1;
  145.     if (lastByte > handlePtr->descPtr->lastByte) {
  146.     lastByte = handlePtr->descPtr->lastByte;
  147.     }
  148.     lastBlock = lastByte / FS_BLOCK_SIZE;
  149.  
  150.     (void)FsGetFirstIndex(handlePtr, firstBlock, &indexInfo);
  151.  
  152.     bufferIndex = 0;
  153.     blockOffset = offset & FS_BLOCK_OFFSET_MASK;
  154. #ifdef SCSI0_BOOT 
  155.     Mach_MonPrintf(" read %d at %d into %x\n", numBytes, offset, buffer);
  156. #endif 
  157.  
  158.     while (indexInfo.blockNum <= lastBlock) {
  159.     if (indexInfo.blockNum < lastBlock) {
  160.         size = FS_BLOCK_SIZE - blockOffset;
  161.         readSize = FS_BLOCK_SIZE;
  162.     } else {
  163.         size = (lastByte & FS_BLOCK_OFFSET_MASK) + 1 - blockOffset;
  164.         readSize = size;
  165.     }
  166.     blockAddr = *indexInfo.blockAddrPtr + 
  167.             fsDomainPtr->headerPtr->dataOffset * FS_FRAGMENTS_PER_BLOCK;
  168.     if (blockOffset != 0 || size != FS_BLOCK_SIZE) { 
  169.         status = FsDeviceBlockIO(FS_READ, &fsDevice, blockAddr,
  170.                (readSize - 1) / FS_FRAGMENT_SIZE + 1, readBuffer);
  171.         if (status != SUCCESS) {
  172.         goto readError;
  173.         }
  174.         bcopy(&(readBuffer[blockOffset]), &(buffer[bufferIndex]), size);
  175.     } else {
  176.         status = FsDeviceBlockIO(FS_READ, &fsDevice, blockAddr,
  177.             FS_FRAGMENTS_PER_BLOCK, &(buffer[bufferIndex]));
  178.         if (status != SUCCESS) {
  179.         goto readError;
  180.         }
  181.     }
  182.     bufferIndex += size;
  183.     blockOffset = 0;
  184.     FsGetNextIndex(handlePtr, &indexInfo);
  185.     }
  186.  
  187. readError:
  188.  
  189.     *readCountPtr = bufferIndex;
  190.  
  191.     return(status);
  192. }
  193.  
  194. /*
  195.  *----------------------------------------------------------------------
  196.  *
  197.  * FsFindComponent --
  198.  *
  199.  *
  200.  * Results:
  201.  *    None.
  202.  *
  203.  * Side effects:
  204.  *
  205.  *----------------------------------------------------------------------
  206.  */
  207. ReturnStatus
  208. FsFindComponent(domainPtr, curHandlePtr, component, newHandlePtrPtr)
  209.     Fsdm_Domain *domainPtr;
  210.     Fsio_FileIOHandle *curHandlePtr;
  211.     char *component;
  212.     Fsio_FileIOHandle **newHandlePtrPtr;
  213. {
  214.     register ReturnStatus status;
  215.     register int dirOffset;        /* Offset within the directory */
  216.     register int blockOffset;        /* Offset within a directory block */
  217.     register Fslcl_DirEntry *dirEntryPtr;    /* Reference to directory entry */
  218.     int length;                /* Length variable for read call */
  219.     register Fsio_FileIOHandle *handlePtr;
  220.  
  221.     dirOffset = 0;
  222.     do {
  223.     length = FSLCL_DIR_BLOCK_SIZE;
  224.     status = Fs_Read(curHandlePtr, dirOffset, length, readBuffer, &length);
  225.     if (status != SUCCESS) {
  226.         return(status);
  227.     }
  228.     if (length == 0) {
  229.         return(FS_FILE_NOT_FOUND);
  230.     }
  231.     dirEntryPtr = (Fslcl_DirEntry *)readBuffer;
  232.     blockOffset = 0;
  233.     while (blockOffset < FSLCL_DIR_BLOCK_SIZE) {
  234.         dirEntryPtr = (Fslcl_DirEntry *)((int)readBuffer + blockOffset);
  235.         if (dirEntryPtr->fileNumber != 0) {
  236.         /*
  237.          * A valid directory record.
  238.          */
  239. #ifndef NO_PRINTF
  240.         Mach_MonPrintf("Found %s\n", dirEntryPtr->fileName);
  241. #endif NO_PRINTF
  242.         if (*dirEntryPtr->fileName=='\0') {
  243.         /*
  244.          * This check is a hack.  Something else should be done.
  245.          */
  246.             return (FS_FILE_NOT_FOUND);
  247.         }
  248.         if (strcmp(component, dirEntryPtr->fileName) == 0) {
  249.             handlePtr = (Fsio_FileIOHandle *)malloc(sizeof(Fsio_FileIOHandle));
  250.             FsInitFileHandle(domainPtr, dirEntryPtr->fileNumber,
  251.                     handlePtr);
  252.             *newHandlePtrPtr = handlePtr;
  253.             return(SUCCESS);
  254.         }
  255.         }
  256.         blockOffset += dirEntryPtr->recordLength;
  257.     }
  258.     dirOffset += FSLCL_DIR_BLOCK_SIZE;
  259.     } while(TRUE);
  260. }
  261.  
  262. /*
  263.  *----------------------------------------------------------------------
  264.  *
  265.  * FsInitFileHandle --
  266.  *
  267.  *    Initialize a file handle.
  268.  *
  269.  * Results:
  270.  *    None.
  271.  *
  272.  * Side effects:
  273.  *    Fills in the file handle that our caller has already allocated.
  274.  *
  275.  *----------------------------------------------------------------------
  276.  */
  277. void
  278. FsInitFileHandle(domainPtr, fileNumber, handlePtr)
  279.     Fsdm_Domain *domainPtr;
  280.     int fileNumber;
  281.     register Fsio_FileIOHandle *handlePtr;
  282. {
  283.     register Fsdm_FileDescriptor *descPtr;
  284.  
  285.     bzero((Address)handlePtr, sizeof(Fsio_FileIOHandle));
  286. #undef minor
  287.     handlePtr->hdr.fileID.minor = fileNumber;
  288.     descPtr = (Fsdm_FileDescriptor *)malloc(sizeof(Fsdm_FileDescriptor));
  289.     FsGetFileDesc(domainPtr, fileNumber, descPtr);
  290.     handlePtr->descPtr = descPtr;
  291. }
  292.  
  293. /*
  294.  *----------------------------------------------------------------------
  295.  *
  296.  * FsGetFileDesc --
  297.  *
  298.  *    Read in a file descriptor from the disk.
  299.  *
  300.  * Results:
  301.  *    None.
  302.  *
  303.  * Side effects:
  304.  *    Fills in the file descriptor that our caller has already allocated.
  305.  *
  306.  *----------------------------------------------------------------------
  307.  */
  308. void
  309. FsGetFileDesc(domainPtr, fileNumber, descPtr)
  310.     Fsdm_Domain *domainPtr;
  311.     register int fileNumber;
  312.     register Fsdm_FileDescriptor *descPtr;
  313. {
  314.     register Ofs_DomainHeader *headerPtr;
  315.     register int         blockNum;
  316.     register int         offset;
  317.  
  318.     headerPtr = domainPtr->headerPtr;
  319.     blockNum = headerPtr->fileDescOffset + fileNumber / FSDM_FILE_DESC_PER_BLOCK;
  320.     offset = (fileNumber & (FSDM_FILE_DESC_PER_BLOCK - 1)) *
  321.         FSDM_MAX_FILE_DESC_SIZE;
  322.  
  323.     (void)FsDeviceBlockIO(FS_READ, &fsDevice, 
  324.                blockNum * FS_FRAGMENTS_PER_BLOCK,
  325.                FS_FRAGMENTS_PER_BLOCK, readBuffer);
  326.     bcopy( readBuffer + offset, descPtr, sizeof(Fsdm_FileDescriptor));
  327. #ifndef NO_PRINTF
  328.     if (descPtr->magic != FSDM_DISK_MAGIC) {
  329.     Mach_MonPrintf("desc %d bad <%x>\n", fileNumber, descPtr->magic);
  330.     }
  331. #endif
  332. }
  333.